#include "Module_Definitions.h"

static void CC_choseprofiles(void)
{
	if (cgGLIsProfileSupported(CG_PROFILE_FP30))  // Advanced Fragment Profile 
		 fragmentprofile = CG_PROFILE_FP30;
	 else if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1))  // Standard Frag Profile
		 fragmentprofile = CG_PROFILE_ARBFP1;
	 else
	 {
		 fprintf(stderr, "Video card does not support fragment programs, exiting...\n");
		 exit(-1);
	 }
	 if (cgGLIsProfileSupported(CG_PROFILE_VP30))  // Advanced Vertex Profile 
		 vertexprofile = CG_PROFILE_VP30;
	 else if (cgGLIsProfileSupported(CG_PROFILE_ARBVP1))  // Standard Vertex Profile
		 vertexprofile = CG_PROFILE_ARBVP1;
	 else
	 {
		 fprintf(stderr, "Video card does not support vertex programs, exiting...\n");
		 exit(-1);
	 }
}
// Functions for Primary CCR
static void CC_loadparams_primary(void)
{

 // Non-uniform inputs in file
 testTextureParam = cgGetNamedParameter(fragmentProgram, "testTexture");
 CheckCgError();
 decalCoordsParam = cgGetNamedParameter(fragmentProgram, "IN.decalCoords");
 CheckCgError();
}

 void keyboard_primary(unsigned char key, int x, int y)
 {
	primary_ccr();
	
	CC_loadparams_primary();

	glutPostRedisplay();
 }

// Image Displaying
 static void Display_image(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	cgGLBindProgram(fragmentProgram);
	CheckCgError();

	cgGLBindProgram(vertexProgram);
	CheckCgError();

	if (load)
	{
		if (image)
		{
            if (load_texture("lenna.bmp"))
				printf("Texture Read Sucessful...\n");
		}
		else
		{
            if (load_texture("face.ppm"))
				printf("Texture Read Sucessful...\n");
		}

		cgGLSetTextureParameter(testTextureParam, g_Texture.id);

		cgGLEnableTextureParameter(testTextureParam);
		load = false;
	}

	cgGLEnableProfile(fragmentprofile);
	cgGLEnableProfile(vertexprofile);

	glBegin(GL_QUADS);
		glVertex2f(-1, -1);
		glVertex2f(-1, 1);
		glVertex2f(1, 1);
		glVertex2f(1, -1);
	glEnd();

	cgGLDisableTextureParameter(testTextureParam);
	
	cgGLDisableProfile(fragmentprofile);
	cgGLDisableProfile(vertexprofile);

	glutSwapBuffers();
}

static void InitializeGlut(int *argc, char *argv[])
{
	glutInit(argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutCreateWindow("Primary Colour Correction");
	glutDisplayFunc(Display_image);
}

 int main(int argc, char *argv[])
 {
	 InitializeGlut(&argc, argv);

	 CC_choseprofiles();

	 // Test Cg Context creation
	 Context = cgCreateContext();
	 CheckCgError();

	 // Test adding source text to context
     fragmentProgram = cgCreateProgramFromFile(Context,
                                    CG_SOURCE, CWD "ccr_fragment.cg",
                                    fragmentprofile,
                                    "main", NULL);

	 CheckCgError();
	 
	 fprintf(stderr, "LAST LISTING----%s----\n", cgGetLastListing(Context));

	 fprintf(stderr, "---- PROGRAM BEGIN ----\n%s---- PROGRAM END ----\n",
        cgGetProgramString(fragmentProgram, CG_COMPILED_PROGRAM));

	 if (fragmentProgram != NULL)
	 {
		 cgGLLoadProgram(fragmentProgram);
		 CheckCgError();
	 }

	 vertexProgram = cgCreateProgramFromFile(Context,
                                    CG_SOURCE, CWD "ccr_vertex.cg",
                                    vertexprofile,
                                    "ccr_vertex", NULL);
	 CheckCgError();

 	 fprintf(stderr, "LAST LISTING----%s----\n", cgGetLastListing(Context));

	 fprintf(stderr, "---- PROGRAM BEGIN ----\n%s---- PROGRAM END ----\n",
        cgGetProgramString(vertexProgram, CG_COMPILED_PROGRAM));

	 if (vertexProgram != NULL)
	 {
		 cgGLLoadProgram(vertexProgram);
		 CheckCgError();
	 }

	 if (fragmentProgram != NULL && vertexProgram != NULL)
	 {
         CC_loadparams_primary();
	 }

     glutKeyboardFunc(keyboard_primary);

     glutMainLoop();

	 cgDestroyProgram(fragmentProgram);
	 cgDestroyProgram(vertexProgram);

	 cgDestroyContext(Context);

	 glDeleteTextures(1, &g_Texture.id);

	 return 0;
 }